#ifndef CHORDTORRENT_TIMER_HXX
#define CHORDTORRENT_TIMER_HXX

#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/thread.hpp>

#include <map>

class Timer;
typedef boost::shared_ptr<Timer> TimerPtr;

class Timer : public boost::enable_shared_from_this<Timer>
{
public:
	class TimerCallback;

	class TimerData 
	{
	public:
		TimerData(void *userData, unsigned int interval, TimerPtr timer) : mTimer(timer), mInterval(interval), mUserData(userData) {}

		void *getUserData() const;
		void cancelTimer();
		unsigned int getInterval() const { return mInterval; }
		
	protected:
		TimerPtr mTimer;
		unsigned int mInterval;
		void *mUserData;
	};

	typedef boost::shared_ptr<TimerData> TimerDataPtr;

	class TimerCallback
	{
	public:
		virtual void onTimer(TimerDataPtr timerData) = 0;
	};

	virtual TimerDataPtr addTimer(TimerCallback *callback, void *userData, unsigned int interval);

	Timer();
	virtual ~Timer();

	static double getTime();

	struct TimerMapData
	{
		TimerMapData(TimerCallback *callback, double lastTime, TimerDataPtr ptr) : mCallback(callback), mLastFireTime(lastTime), mTimerData(ptr) {}
		TimerMapData() : mCallback(0), mLastFireTime(0) {}

		TimerCallback *mCallback;
		double mLastFireTime;
		TimerDataPtr mTimerData;
	};

protected:
	std::map<void *, TimerMapData> mTimerMap;
	boost::shared_ptr<boost::thread> mThread;
	bool mCanExit;

	void onThreadRun();
	void checkThread();
};

#endif
